package org.dragon.services.impls;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.dragon.commons.*;
import org.dragon.models.RedisSessionAccount;
import org.dragon.services.SessionAccountService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * Author:     Zhao Yan
 * DateTime:   2023/5/18 9:15
 */
@Service
public class RedisSessionAccountServiceImpl implements SessionAccountService {

    @Resource
    private JsonRedisTemplate jsonRedisTemplate;

    // 从 redis 查询 session account
    @Override
    public RedisSessionAccount query(String token) {
        Object o = jsonRedisTemplate.opsForValue().get(token);

        if (o instanceof RedisSessionAccount account)
            return account;
        return null;
    }

    @Override
    public RedisSessionAccount query(String token, HttpServletRequest request) {
        return getRedisSessionAccount(token, request);
    }

    private RedisSessionAccount getRedisSessionAccount(String token, HttpServletRequest request) {
        String key = Const.ACCOUNT;
        Object account = request.getAttribute(key);

        if (account instanceof RedisSessionAccount redisSessionAccount)
            return redisSessionAccount;

        Object o = jsonRedisTemplate.opsForValue().get(token);

        if (o instanceof RedisSessionAccount a) {
            request.setAttribute(key, a);
            return a;
        }

        return null;
    }

    @Override
    public RedisSessionAccount query(HttpServletRequest request) {
        String token = Web.getToken(request);

        if (!StringUtils.hasText(token))
            throw new ApplicationException(Errors.InvalidCredential);

        RedisSessionAccount query = getRedisSessionAccount(token, request);

        if (query == null)
            throw new ApplicationException(Errors.TokenExpired);

        return query;
    }

    @Override
    public void save(String token, RedisSessionAccount account, long timeoutInMinutes) {
        if (StringUtils.hasLength(token))
            jsonRedisTemplate.opsForValue().set(token, account, timeoutInMinutes, TimeUnit.MINUTES);
    }
}
